/**
 * 20220302:更改three引入方式
 * 20220711:rewrite with typescript
 */

 import {MathUtils, WebGLRenderer} from 'three';
 import {Props,Prop} from "./props";
import {RatioRect, SceneManager} from './scene-manager';
 
interface WorkSpaceProps{
    active:Prop<boolean>,reset:Prop<boolean>
}

 /**
  * logic work scene
  */
 export default abstract class WorkSpace{

    protected params:Array<any>;
    private _firstRender:boolean;
    private _props!:Props<WorkSpaceProps>;

    public readonly spaceName:string='defaultSpace';
    public readonly uuid:string;

    constructor(...params:Array<any>){
        this.params=params;
         this.uuid=MathUtils.generateUUID();
         this._firstRender=true;
         this.initProps();
         this.initComponents();
         this.initPropCallback();
         this.initialize();
    }
 
    //---------------------------------对外属性及方法----------------------------------
 
    public get active():boolean{
         return (this._props as any).map.active.value;
    }
    public set active(bol:boolean){
         (this._props as any).map.active.value=bol;
    }
 
    public set reset(bol:boolean){
         (this._props as any).map.reset.value=bol;
    }
 
    public get props():Props<WorkSpaceProps>|null{
         return this._props;
    }
 
    public render(renderer:WebGLRenderer,time:number,frame:XRFrame):void{
        if(this._firstRender){
            this.onFirstRender(renderer);
            this._firstRender=false;
        }
    }
    public abstract resize(size:RatioRect):void;
    public dispose(sceneManager?:SceneManager|null):void{
        if(sceneManager)sceneManager.removeFromQueue(this);
        this._props!.dispose();
    }
 
     //--------------------------------------------内部方法------------------------------------
 
    protected abstract onActive(bol:boolean):void;
    protected abstract onReset():void;
    protected onFirstRender(renderer:WebGLRenderer):void{}
    protected abstract initComponents():void;
    protected abstract initialize():void;
    protected initProps():void{
        this._props=new Props({
            active:false,
            reset:false,
        });
    }
    protected initPropCallback():void{
        this._props!.onKeyChange('active',(_new:boolean,_old:boolean):void=>{
            this.onActive(_new);
        });
        this._props!.onKeyChange('reset',(_new:boolean,_old:boolean):void=>{
            if((this._props as any).reset.value){
                this.onReset();
                (this._props as any).reset.value=false;
            }
        });
    }
}